package com.zn.filter;

import com.alibaba.fastjson.JSONObject;
import com.netflix.zuul.ZuulFilter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import com.netflix.zuul.context.RequestContext;
import com.zn.util.AESEncrypt;
import com.zn.util.Constant;
import com.zn.vo.Message;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;

import java.io.ByteArrayInputStream;
import java.util.Arrays;
import java.util.List;


@Configuration
public class TokenFilter extends ZuulFilter {
    private static final Logger LOGGER = LoggerFactory.getLogger(TokenFilter.class);
    @Value("${token.filter.method.uri}")
    private String URI_STR;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Value("${aesKey}")
    private String aesKey;

    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 1;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 校验token的拦截器
     * @return
     */
    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        /*******************处理H5跨域问题**************************/
        HttpServletResponse response=ctx.getResponse();
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT,DELETE, PATCH");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
//        response.setHeader("Access-Control-Expose-Headers", "Location");
        response.setCharacterEncoding("utf-8");
        /*******************处理H5跨域问题*************************/
        LOGGER.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
        String requestURI = request.getRequestURI().toString();
        LOGGER.info("uri:" + requestURI + "PROPERTIRS:" + URI_STR);
        List<String> uriList= Arrays.asList(URI_STR.split(","));
        /**校验token是否为空并且不存在于不需要拦截的方法内 则返回需要token**/
        /**判断接口是否需要校验token 不存在list则需要校验**/
        String accessToken="",customerTel="",version="";
        /**获取请求头中的token**/
        try{
            /**解密**/
            /**解密**/
            if(StringUtils.isNotBlank(request.getHeader("accessToken"))){
                accessToken=AESEncrypt.aesDecrypt(request.getHeader("accessToken"), aesKey);
            }
            if(StringUtils.isNotBlank(request.getHeader("customerTel"))){
                customerTel=AESEncrypt.aesDecrypt(request.getHeader("customerTel"), aesKey);
            }
            if(StringUtils.isNotBlank(request.getHeader("version"))){
                version = AESEncrypt.aesDecrypt(request.getHeader("version"), aesKey);
            }
        }catch (Exception e){
            LOGGER.error("解密头信息异常..."+e);
            Message message=new Message();
            message.setResCode("500");
            message.setMsg("解密头信息异常");
            forwardErrorHandle(ctx, message);
            return null;
        }
        LOGGER.info("request version........."+version);
        if(!uriList.contains(requestURI)){
            String redisToken=redisTemplate.opsForValue().get(Constant.CUSTOMER_TOKEN_BEFROM+customerTel);
            LOGGER.info("redisToken:"+redisToken+".......key:"+Constant.CUSTOMER_TOKEN_BEFROM+customerTel);
            if (accessToken == null) {
                forwardErrorHandle(ctx,Message.TOKEN_NULL);
                return null;
            }
            /**该用户redis中的token不存在**/
            if(StringUtils.isBlank(redisToken)){
                forwardErrorHandle(ctx,Message.TOKEN_INVALID);
                return null;
            }
            /**token不一致校验**/
            if(!redisToken.equals(accessToken)){
                forwardErrorHandle(ctx,Message.TOKEN_ATYPISM);
                return null;
            }
        }
        LOGGER.info("access token ok");
        return null;
    }

    private void forwardErrorHandle(RequestContext ctx,Message message){
        try {
            /**处理中文乱码**/
            HttpServletResponse response=ctx.getResponse();
            response.setContentType("text/html;charset=utf-8");
            LOGGER.info("access token is empty");
            ctx.setResponse(response);
            /**过滤该请求，不对其进行路由**/
            ctx.setSendZuulResponse(false);
            /**返回错误码**/
            ctx.setResponseStatusCode(200);
            Object json = JSONObject.toJSON(message);
            ctx.set("isSuccess", false);
            /**返回错误内容**/
            byte[] bodys = json.toString().getBytes();
            ctx.setResponseDataStream(new ByteArrayInputStream(bodys));
        }catch (Exception e){
            LOGGER.error("forwardErrorHandle...",e);
        }

    }
}